<?xml version="1.0" encoding="UTF-8" ?>
<!--

    Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
    under one or more contributor license agreements. See the NOTICE file
    distributed with this work for additional information regarding copyright
    ownership. Camunda licenses this file to you under the Apache License,
    Version 2.0; you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.camunda.bpm.engine.impl.persistence.entity.JobEntity">

  <!-- JOB DELETE STATEMENTS-->

  <delete id="deleteJob" parameterType="org.camunda.bpm.engine.impl.persistence.entity.JobEntity">
    delete from ${prefix}ACT_RU_JOB where ID_ = #{id} and REV_ = #{revision}
  </delete>

  <delete id="deleteTimer" parameterType="org.camunda.bpm.engine.impl.persistence.entity.JobEntity">
    delete from ${prefix}ACT_RU_JOB where ID_ = #{id} and REV_ = #{revision}
  </delete>

  <delete id="deleteMessage" parameterType="org.camunda.bpm.engine.impl.persistence.entity.JobEntity">
    delete from ${prefix}ACT_RU_JOB where ID_ = #{id} and REV_ = #{revision}
  </delete>

  <delete id="deleteEverLivingJob" parameterType="org.camunda.bpm.engine.impl.persistence.entity.JobEntity">
    delete from ${prefix}ACT_RU_JOB where ID_ = #{id} and REV_ = #{revision}
  </delete>

  <!-- JOB UPDATE STATEMENTS-->

  <update id="updateJobSuspensionStateByParameters" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    update ${prefix}ACT_RU_JOB set
      REV_ = 1 + REV_ ,
      SUSPENSION_STATE_ = #{parameter.suspensionState, jdbcType=INTEGER}
    <where>
      <if test="parameter.jobId != null">
        ID_ = #{parameter.jobId, jdbcType=VARCHAR}
      </if>
      <if test="parameter.jobDefinitionId != null">
        and JOB_DEF_ID_ = #{parameter.jobDefinitionId, jdbcType=VARCHAR}
      </if>
      <if test="parameter.processInstanceId != null">
        and PROCESS_INSTANCE_ID_ = #{parameter.processInstanceId, jdbcType=VARCHAR}
      </if>
      <if test="parameter.processDefinitionId != null">
        and PROCESS_DEF_ID_ = #{parameter.processDefinitionId, jdbcType=VARCHAR}
      </if>
      <if test="parameter.processDefinitionKey != null">
        <if test="!parameter.isProcessDefinitionTenantIdSet">
          and PROCESS_DEF_KEY_ = #{parameter.processDefinitionKey, jdbcType=VARCHAR}
        </if>
        <if test="parameter.isProcessDefinitionTenantIdSet">
          and PROCESS_DEF_ID_ IN (
            SELECT ID_ 
            FROM ${prefix}ACT_RE_PROCDEF PD
            WHERE PD.KEY_ = #{parameter.processDefinitionKey, jdbcType=VARCHAR}
            <if test="parameter.processDefinitionTenantId != null">
              and PD.TENANT_ID_ = #{parameter.processDefinitionTenantId, jdbcType=VARCHAR}
            </if>
            <if test="parameter.processDefinitionTenantId == null">
              and PD.TENANT_ID_ is null
            </if>
          )
        </if>
        <bind name="columnPrefix" value="''"/>
        <include refid="org.camunda.bpm.engine.impl.persistence.entity.TenantEntity.queryTenantCheckWithPrefix" />
      </if>
      <if test="parameter.handlerType != null">
        and HANDLER_TYPE_ =  #{parameter.handlerType, jdbcType=VARCHAR}
      </if>
    </where>
  </update>

  <update id="updateFailedJobRetriesByParameters" parameterType="java.util.Map">
    update ${prefix}ACT_RU_JOB set
      REV_ = 1 + REV_ ,
      LOCK_OWNER_ = NULL,
      LOCK_EXP_TIME_ = NULL,
      <if test="isDueDateSet">
        DUEDATE_ = #{dueDate, jdbcType=TIMESTAMP},
      </if>
      RETRIES_ = #{retries, jdbcType=INTEGER}
    <where>
      RETRIES_ = 0
      <if test="jobDefinitionId != null">
        and JOB_DEF_ID_ = #{jobDefinitionId, jdbcType=VARCHAR}
      </if>
    </where>
  </update>

  <update id="updateJobPriorityByDefinitionId" parameterType="java.util.Map">
    <!-- this does not increment revision; it is ok if this update is overwritten by parallel operations -->
    update ${prefix}ACT_RU_JOB set
      PRIORITY_ = #{priority, jdbcType=INTEGER}
    where
      JOB_DEF_ID_ = #{jobDefinitionId, jdbcType=VARCHAR}
  </update>

  <!-- JOB RESULTMAP (FOR TIMER AND MESSAGE) -->

  <resultMap id="jobResultMap" type="org.camunda.bpm.engine.impl.persistence.entity.JobEntity">
    <id property="id" column="ID_" jdbcType="VARCHAR" />
    <result property="revision" column="REV_" jdbcType="INTEGER" />
    <result property="lockOwner" column="LOCK_OWNER_" jdbcType="VARCHAR" />
    <result property="lockExpirationTime" column="LOCK_EXP_TIME_" jdbcType="TIMESTAMP" />
    <result property="exclusive" column="EXCLUSIVE_" jdbcType="BOOLEAN" />
    <result property="executionId" column="EXECUTION_ID_" jdbcType="VARCHAR" />
    <result property="processInstanceId" column="PROCESS_INSTANCE_ID_" jdbcType="VARCHAR" />
    <result property="processDefinitionId" column="PROCESS_DEF_ID_" jdbcType="VARCHAR" />
    <result property="processDefinitionKey" column="PROCESS_DEF_KEY_" jdbcType="VARCHAR" />
    <result property="retriesFromPersistence" column="RETRIES_" jdbcType="INTEGER" />
    <result property="exceptionByteArrayId" column="EXCEPTION_STACK_ID_" jdbcType="VARCHAR" />
    <result property="failedActivityId" column="FAILED_ACT_ID_" jdbcType="VARCHAR" />
    <result property="exceptionMessage" column="EXCEPTION_MSG_" jdbcType="VARCHAR" />
    <result property="duedate" column="DUEDATE_" jdbcType="TIMESTAMP" />
    <result property="jobHandlerType" column="HANDLER_TYPE_" jdbcType="VARCHAR" />
    <result property="jobHandlerConfigurationRaw" column="HANDLER_CFG_" jdbcType="VARCHAR" />
    <result property="deploymentId" column="DEPLOYMENT_ID_" jdbcType="VARCHAR" />
    <result property="suspensionState" column="SUSPENSION_STATE_" jdbcType="INTEGER"/>
    <result property="jobDefinitionId" column="JOB_DEF_ID_" jdbcType="VARCHAR" />
    <result property="priority" column="PRIORITY_" jdbcType="BIGINT" />
    <result property="tenantId" column="TENANT_ID_" jdbcType="VARCHAR" />
    <result property="createTime" column="CREATE_TIME_" jdbcType="TIMESTAMP" />
    <result property="sequenceCounter" column="SEQUENCE_COUNTER_" jdbcType="BIGINT" />
    <result property="lastFailureLogId" column="LAST_FAILURE_LOG_ID_" jdbcType="VARCHAR" />
    <discriminator javaType="string" column="TYPE_">
      <case value="message" resultMap="messageResultMap"/>
      <case value="timer" resultMap="timerResultMap"/>
      <case value="ever-living" resultMap="everLivingJobResultMap"/>
    </discriminator>
  </resultMap>

  <resultMap id="messageResultMap" type="org.camunda.bpm.engine.impl.persistence.entity.MessageEntity" extends="jobResultMap"/>

  <resultMap id="everLivingJobResultMap" type="org.camunda.bpm.engine.impl.persistence.entity.EverLivingJobEntity" extends="jobResultMap"/>

  <resultMap id="timerResultMap" type="org.camunda.bpm.engine.impl.persistence.entity.TimerEntity" extends="jobResultMap">
    <result property="repeat" column="REPEAT_" jdbcType="VARCHAR" />
    <result property="repeatOffset" column="REPEAT_OFFSET_" jdbcType="BIGINT" />
  </resultMap>

  <resultMap id="acquirableJobResultMap" type="org.camunda.bpm.engine.impl.persistence.entity.AcquirableJobEntity">
    <id property="id" column="ID_" jdbcType="VARCHAR" />
    <result property="revision" column="REV_" jdbcType="INTEGER" />
    <result property="duedate" column="DUEDATE_" jdbcType="TIMESTAMP" />
    <result property="processInstanceId" column="PROCESS_INSTANCE_ID_" jdbcType="VARCHAR" />
    <result property="exclusive" column="EXCLUSIVE_" jdbcType="BOOLEAN" />
  </resultMap>

  <resultMap type="org.camunda.bpm.engine.impl.util.ImmutablePair" id="deploymentIdMapping">
    <id property="left" column="DEPLOYMENT_ID_" jdbcType="VARCHAR" />
    <id property="right" column="ID_" jdbcType="VARCHAR" />
  </resultMap>


  <!-- JOB SELECT (FOR TIMER AND MESSAGE) -->

  <select id="selectJob" parameterType="string" resultMap="jobResultMap">
    select * from ${prefix}ACT_RU_JOB where ID_ = #{id}
  </select>

  <select id="selectNextJobsToExecute" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="acquirableJobResultMap">
    <bind name="orderingProperties" value="parameter.orderingProperties" />
    <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.bindOrderBy"/>
    ${limitBefore}
    select RES.ID_,
      RES.REV_,
      RES.DUEDATE_,
      RES.PROCESS_INSTANCE_ID_,
      RES.EXCLUSIVE_
    ${limitBetweenAcquisition}
    from ${prefix}ACT_RU_JOB RES

    where (RES.RETRIES_ &gt; 0)
      and (
      <if test="!parameter.alwaysSetDueDate">
          RES.DUEDATE_ is null or
      </if>
          RES.DUEDATE_ &lt;= #{parameter.now, jdbcType=TIMESTAMP}
      )
      and (RES.LOCK_OWNER_ is null or RES.LOCK_EXP_TIME_ &lt; #{parameter.now, jdbcType=TIMESTAMP})
      and RES.SUSPENSION_STATE_ = 1

      <if test="parameter.deploymentAware">
        and (RES.DEPLOYMENT_ID_ is null
        <if test="parameter.deploymentIds != null">
          or
          <bind name="listOfIds" value="parameter.deploymentIds"/>
          <bind name="fieldName" value="'RES.DEPLOYMENT_ID_'"/>
          <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.applyInForPaginatedCollection"/>
        </if>
        )
      </if>

      <if test="parameter.jobPriorityMin != null">
        and RES.PRIORITY_ &gt;= #{parameter.jobPriorityMin}
      </if>
      <if test="parameter.jobPriorityMax != null">
        and RES.PRIORITY_ &lt;= #{parameter.jobPriorityMax}
      </if>

      and (<include refid="AtomicExclusiveOrNonExclusiveJobs"/>)

      <if test="!parameter.historyCleanupEnabled">
        and HANDLER_TYPE_ != 'history-cleanup'
      </if>

    <if test="parameter.applyOrdering">
      ${orderBy}
    </if>
    ${limitAfter}
  </select>

  <sql id="AtomicExclusiveOrNonExclusiveJobs">
    (<include refid="AtomicExclusiveJobs"/>)
    or
    <include refid="NonExclusiveJobs"/>
  </sql>

  <sql id="AtomicExclusiveJobs">
    RES.EXCLUSIVE_ = ${trueConstant}
          and not exists(
            select J2.ID_ from ${prefix}ACT_RU_JOB J2
            where J2.PROCESS_INSTANCE_ID_ = RES.PROCESS_INSTANCE_ID_                                           -- from the same proc. inst.
            and (J2.EXCLUSIVE_ = ${trueConstant})                                                              -- also exclusive
            and (J2.LOCK_OWNER_ is not null and J2.LOCK_EXP_TIME_ &gt;= #{parameter.now, jdbcType=TIMESTAMP})  -- in progress
            )
  </sql>

  <sql id="NonExclusiveJobs">
    RES.EXCLUSIVE_ = ${falseConstant}
  </sql>

  <select id="selectJobsByConfiguration" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="jobResultMap">
      select * from ${prefix}ACT_RU_JOB
      where HANDLER_TYPE_ = #{parameter.handlerType}
      <if test="parameter.tenantId != null">
        and TENANT_ID_ = #{parameter.tenantId}
      </if>
      <if test="parameter.tenantId == null">
        and TENANT_ID_ is null
      </if>
      and (HANDLER_CFG_ = #{parameter.handlerConfiguration, jdbcType=VARCHAR}
      <if test="parameter.handlerConfigurationWithFollowUpJobCreatedProperty != null">
      or HANDLER_CFG_ = #{parameter.handlerConfigurationWithFollowUpJobCreatedProperty, jdbcType=VARCHAR}
      </if>)
  </select>

    <select id="selectJobsByHandlerType" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="jobResultMap" flushCache="true">
        select * from ${prefix}ACT_RU_JOB
        where HANDLER_TYPE_ = #{parameter}
    </select>

  <select id="selectJobsByExecutionId" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="jobResultMap">
    select *
    from ${prefix}ACT_RU_JOB J
    where J.EXECUTION_ID_ = #{parameter}
  </select>

  <select id="selectJobsByProcessInstanceId" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="jobResultMap">
    select *
    from ${prefix}ACT_RU_JOB J
    where J.PROCESS_INSTANCE_ID_ = #{parameter}
  </select>

  <select id="selectJobsByJobDefinitionId" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="jobResultMap">
    select *
    from ${prefix}ACT_RU_JOB J
    where J.JOB_DEF_ID_ = #{parameter}
  </select>

  <select id="selectJobByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.JobQueryImpl" resultMap="jobResultMap">
  	<include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.bindOrderBy"/>
    ${limitBefore}
    select ${distinct} RES.*
    ${limitBetween}
    <include refid="selectJobByQueryCriteriaSql"/>
    ${orderBy}
    ${limitAfter}
  </select>

  <select id="selectJobCountByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.JobQueryImpl" resultType="long">
    ${countDistinctBeforeStart} RES.ID_ ${countDistinctBeforeEnd}
    <include refid="selectJobByQueryCriteriaSql"/>
    ${countDistinctAfterEnd}
  </select>

  <select id="selectJobDeploymentIdMappingsByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.JobQueryImpl" resultMap="deploymentIdMapping">
    select distinct RES.DEPLOYMENT_ID_, RES.ID_
    <include refid="selectJobByQueryCriteriaSql"/>
    ORDER BY RES.DEPLOYMENT_ID_ ASC
  </select>

  <sql id="selectJobByQueryCriteriaSql">
    from ${prefix}ACT_RU_JOB RES
    <if test="executable">
        LEFT OUTER JOIN ${prefix}ACT_RU_EXECUTION PI ON PI.ID_ = RES.PROCESS_INSTANCE_ID_
    </if>
    <if test="activityId != null">
      LEFT OUTER JOIN ${prefix}ACT_RU_JOBDEF JD ON JD.ID_ = RES.JOB_DEF_ID_
    </if>
    <where>
      <if test="id != null">
        RES.ID_ = #{id}
      </if>
      <if test="ids != null and !ids.isEmpty()">
        <bind name="listOfIds" value="ids" />
        <bind name="fieldName" value="'RES.ID_'" />
        <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.applyInForPaginatedCollection" />
      </if>
      <if test="jobDefinitionId != null">
        RES.JOB_DEF_ID_ = #{jobDefinitionId}
      </if>
      <if test="activityId != null">
      	JD.ACT_ID_ = #{activityId}
      </if>
      <if test="processInstanceId != null">
        and RES.PROCESS_INSTANCE_ID_ = #{processInstanceId}
      </if>
      <if test="processInstanceIds != null and !processInstanceIds.isEmpty()">
        <bind name="listOfIds" value="processInstanceIds" />
        <bind name="fieldName" value="'RES.PROCESS_INSTANCE_ID_'" />
        <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.applyInForPaginatedCollection" />
      </if>
      <if test="executionId != null">
        and RES.EXECUTION_ID_ = #{executionId}
      </if>
      <if test="processDefinitionId != null">
        and RES.PROCESS_DEF_ID_ = #{processDefinitionId}
      </if>
      <if test="processDefinitionKey != null">
        and RES.PROCESS_DEF_KEY_ = #{processDefinitionKey}
      </if>
      <if test="retriesLeft">
        and RES.RETRIES_ &gt; 0
      </if>
      <if test="executable">
        and (RES.RETRIES_ &gt; 0)
        and (RES.DUEDATE_ is null or RES.DUEDATE_ &lt;= #{now, jdbcType=TIMESTAMP})
        and (
            (RES.EXECUTION_ID_ is null)
            or
            (PI.SUSPENSION_STATE_ = 1 or PI.SUSPENSION_STATE_ is null)
      )
      </if>
      <if test="onlyTimers">
        and RES.TYPE_ = 'timer'
      </if>
      <if test="onlyMessages">
        and RES.TYPE_ = 'message'
      </if>
      <if test="duedateHigherThan != null">
        and RES.DUEDATE_ &gt; #{duedateHigherThan}
      </if>
      <if test="duedateLowerThan != null">
        and RES.DUEDATE_ &lt; #{duedateLowerThan}
      </if>
      <if test="duedateHigherThanOrEqual != null">
        and RES.DUEDATE_ &gt;= #{duedateHigherThanOrEqual}
      </if>
      <if test="duedateLowerThanOrEqual != null">
        and RES.DUEDATE_ &lt;= #{duedateLowerThanOrEqual}
      </if>
      <if test="createdAfter != null">
        and RES.CREATE_TIME_ > #{createdAfter}
      </if>
      <if test="createdBefore != null">
        and RES.CREATE_TIME_ &lt;= #{createdBefore}
      </if>
      <if test="priorityHigherThanOrEqual != null">
        and RES.PRIORITY_ &gt;= #{priorityHigherThanOrEqual}
      </if>
      <if test="priorityLowerThanOrEqual != null">
        and RES.PRIORITY_ &lt;= #{priorityLowerThanOrEqual}
      </if>
      <if test="withException">
      	and (RES.EXCEPTION_MSG_ is not null or RES.EXCEPTION_STACK_ID_ is not null)
      </if>
      <if test="exceptionMessage">
      	and RES.EXCEPTION_MSG_ = #{exceptionMessage}
      </if>
      <if test="failedActivityId != null">
        and RES.FAILED_ACT_ID_ = #{failedActivityId}
      </if>
      <if test="noRetriesLeft">
        and RES.RETRIES_ = 0
      </if>
      <if test="suspensionState != null">
        and RES.SUSPENSION_STATE_ = #{suspensionState.stateCode}
      </if>
      <if test="isTenantIdSet">
        <if test="tenantIds != null &amp;&amp; tenantIds.length > 0">
          and ( RES.TENANT_ID_ in
          <foreach item="tenantId" index="index" collection="tenantIds"
                   open="(" separator="," close=")">
            #{tenantId}
          </foreach>
          <if test="includeJobsWithoutTenantId">
            or RES.TENANT_ID_ is null
          </if>
          )
        </if>
        <if test="tenantIds == null">
          and RES.TENANT_ID_ is null
        </if>
      </if>

      <if test="authCheck.shouldPerformAuthorizatioCheck &amp;&amp; authCheck.authUserId != null">
        AND
          ( CASE

            WHEN
              RES.PROCESS_DEF_KEY_ is not null
            THEN
              (
              <bind name="authUserId" value="authCheck.authUserId" />
              <bind name="authGroupIds" value="authCheck.authGroupIds" />
              <bind name="revokeAuthorizationCheckEnabled" value="authCheck.revokeAuthorizationCheckEnabled" />
              <bind name="permissionChecks" value="authCheck.permissionChecks" />
              <include refid="org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity.authorizationCheck" />)

            ELSE
              <!-- "standalone" job (e.g. job to activate/suspend a process definition etc.) -->
              1
          END ) = 1
      </if>

      <include refid="org.camunda.bpm.engine.impl.persistence.entity.TenantEntity.queryTenantCheck" />

    </where>
  </sql>

  <!-- TIMER INSERT -->

  <insert id="insertTimer" parameterType="org.camunda.bpm.engine.impl.persistence.entity.TimerEntity">
    insert into ${prefix}ACT_RU_JOB (
            ID_,
            TYPE_,
            LOCK_OWNER_,
            LOCK_EXP_TIME_,
            EXCLUSIVE_,
            EXECUTION_ID_,
            PROCESS_INSTANCE_ID_,
            PROCESS_DEF_ID_,
            PROCESS_DEF_KEY_,
            RETRIES_,
            EXCEPTION_STACK_ID_,
            EXCEPTION_MSG_,
            FAILED_ACT_ID_,
            DUEDATE_,
            REPEAT_,
            REPEAT_OFFSET_,
            HANDLER_TYPE_,
            HANDLER_CFG_,
            DEPLOYMENT_ID_,
            SUSPENSION_STATE_,
            JOB_DEF_ID_,
            PRIORITY_,
            SEQUENCE_COUNTER_,
            TENANT_ID_,
            CREATE_TIME_,
            REV_
          )
    values (#{id, jdbcType=VARCHAR},
            'timer',
            #{lockOwner, jdbcType=VARCHAR},
            #{lockExpirationTime, jdbcType=TIMESTAMP},
            #{exclusive, jdbcType=BOOLEAN},
            #{executionId, jdbcType=VARCHAR},
            #{processInstanceId, jdbcType=VARCHAR},
            #{processDefinitionId, jdbcType=VARCHAR},
            #{processDefinitionKey, jdbcType=VARCHAR},
            #{retries, jdbcType=INTEGER},
            #{exceptionByteArrayId, jdbcType=VARCHAR},
            #{exceptionMessage, jdbcType=VARCHAR},
            #{failedActivityId, jdbcType=VARCHAR},
            #{duedate, jdbcType=TIMESTAMP},
            #{repeat, jdbcType=VARCHAR},
            #{repeatOffset, jdbcType=BIGINT},
            #{jobHandlerType, jdbcType=VARCHAR},
            #{jobHandlerConfigurationRaw, jdbcType=VARCHAR},
            #{deploymentId, jdbcType=VARCHAR},
            #{suspensionState, jdbcType=INTEGER},
            #{jobDefinitionId, jdbcType=VARCHAR},
            #{priority, jdbcType=BIGINT},
            #{sequenceCounter, jdbcType=BIGINT},
            #{tenantId, jdbcType=VARCHAR},
            #{createTime, jdbcType=TIMESTAMP},
            1
    )
  </insert>

  <!-- TIMER UPDATE -->

  <update id="updateTimer" parameterType="org.camunda.bpm.engine.impl.persistence.entity.TimerEntity">
    update ${prefix}ACT_RU_JOB
    <set>
       REV_ =  #{revisionNext, jdbcType=INTEGER},
       EXECUTION_ID_ = #{executionId, jdbcType=VARCHAR},
       LOCK_EXP_TIME_ = #{lockExpirationTime, jdbcType=TIMESTAMP},
       LOCK_OWNER_ = #{lockOwner, jdbcType=VARCHAR},
       RETRIES_ = #{retries, jdbcType=INTEGER},
       EXCEPTION_STACK_ID_ = #{exceptionByteArrayId, jdbcType=VARCHAR},
       EXCEPTION_MSG_ = #{exceptionMessage, jdbcType=VARCHAR},
       FAILED_ACT_ID_ = #{failedActivityId, jdbcType=VARCHAR},
       DUEDATE_ = #{duedate, jdbcType=TIMESTAMP},
       REPEAT_ = #{repeat, jdbcType=VARCHAR},
       REPEAT_OFFSET_ = #{repeatOffset, jdbcType=BIGINT},
       SUSPENSION_STATE_ = #{suspensionState, jdbcType=INTEGER},
       PROCESS_DEF_ID_ = #{processDefinitionId, jdbcType=VARCHAR},
       PROCESS_DEF_KEY_ = #{processDefinitionKey, jdbcType=VARCHAR},
       JOB_DEF_ID_ = #{jobDefinitionId, jdbcType=VARCHAR},
       DEPLOYMENT_ID_ = #{deploymentId, jdbcType=VARCHAR},
       HANDLER_CFG_ = #{jobHandlerConfigurationRaw, jdbcType=VARCHAR},
       PRIORITY_ = #{priority, jdbcType=BIGINT},
       SEQUENCE_COUNTER_ = #{sequenceCounter, jdbcType=BIGINT},
       LAST_FAILURE_LOG_ID_ = #{lastFailureLogId, jdbcType=VARCHAR}
    </set>
    where ID_= #{id, jdbcType=VARCHAR}
      and REV_ = #{revision, jdbcType=INTEGER}
  </update>

  <!-- TIMER SELECT -->

  <select id="selectUnlockedTimersByDuedate" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="jobResultMap">
    select *
    from ${prefix}ACT_RU_JOB
    where (TYPE_ = 'timer')
      and (DUEDATE_ is not null)
      and (DUEDATE_ &lt; #{parameter, jdbcType=TIMESTAMP})
      and (LOCK_OWNER_ is null or LOCK_EXP_TIME_ &lt; #{parameter, jdbcType=TIMESTAMP})
      and (RETRIES_  &gt; 0)
    order by DUEDATE_
  </select>

  <select id="selectTimersByExecutionId" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="jobResultMap">
    select *
    from ${prefix}ACT_RU_JOB
    where (RETRIES_ &gt; 0)
      and (TYPE_ = 'timer')
      and (EXECUTION_ID_ = #{parameter})
  </select>

  <!-- MESSAGE INSERT -->

  <insert id="insertMessage" parameterType="org.camunda.bpm.engine.impl.persistence.entity.MessageEntity">
    insert into ${prefix}ACT_RU_JOB (
            ID_,
            TYPE_,
            LOCK_OWNER_,
            LOCK_EXP_TIME_,
            EXCLUSIVE_,
            EXECUTION_ID_,
            PROCESS_INSTANCE_ID_,
            PROCESS_DEF_ID_,
            PROCESS_DEF_KEY_,
            RETRIES_,
            EXCEPTION_STACK_ID_,
            EXCEPTION_MSG_,
            FAILED_ACT_ID_,
            DUEDATE_,
            HANDLER_TYPE_,
            HANDLER_CFG_,
            DEPLOYMENT_ID_,
            SUSPENSION_STATE_,
            JOB_DEF_ID_,
            PRIORITY_,
            SEQUENCE_COUNTER_,
            TENANT_ID_,
            CREATE_TIME_,
            REV_
            )
    values (#{id, jdbcType=VARCHAR},
            'message',
            #{lockOwner, jdbcType=VARCHAR},
            #{lockExpirationTime, jdbcType=TIMESTAMP},
            #{exclusive, jdbcType=BOOLEAN},
            #{executionId, jdbcType=VARCHAR},
            #{processInstanceId, jdbcType=VARCHAR},
            #{processDefinitionId, jdbcType=VARCHAR},
            #{processDefinitionKey, jdbcType=VARCHAR},
            #{retries, jdbcType=INTEGER},
            #{exceptionByteArrayId, jdbcType=VARCHAR},
            #{exceptionMessage, jdbcType=VARCHAR},
            #{failedActivityId, jdbcType=VARCHAR},
            #{duedate, jdbcType=TIMESTAMP},
            #{jobHandlerType, jdbcType=VARCHAR},
            #{jobHandlerConfigurationRaw, jdbcType=VARCHAR},
            #{deploymentId, jdbcType=VARCHAR},
            #{suspensionState, jdbcType=INTEGER},
            #{jobDefinitionId, jdbcType=VARCHAR},
            #{priority, jdbcType=BIGINT},
            #{sequenceCounter, jdbcType=BIGINT},
            #{tenantId, jdbcType=VARCHAR},
            #{createTime, jdbcType=TIMESTAMP},
            1
    )
  </insert>
  <!-- MESSAGE UPDATE -->

  <update id="updateMessage" parameterType="org.camunda.bpm.engine.impl.persistence.entity.MessageEntity">
    update ${prefix}ACT_RU_JOB
    <set>
       REV_ =  #{revisionNext, jdbcType=INTEGER},
       EXECUTION_ID_ = #{executionId, jdbcType=VARCHAR},
       LOCK_EXP_TIME_ = #{lockExpirationTime, jdbcType=TIMESTAMP},
       LOCK_OWNER_ = #{lockOwner, jdbcType=VARCHAR},
       RETRIES_ = #{retries, jdbcType=INTEGER},
       EXCEPTION_STACK_ID_ = #{exceptionByteArrayId, jdbcType=VARCHAR},
       EXCEPTION_MSG_ = #{exceptionMessage, jdbcType=VARCHAR},
       FAILED_ACT_ID_ = #{failedActivityId, jdbcType=VARCHAR},
       DUEDATE_ = #{duedate, jdbcType=TIMESTAMP},
       SUSPENSION_STATE_ = #{suspensionState, jdbcType=INTEGER},
       PROCESS_DEF_ID_ = #{processDefinitionId, jdbcType=VARCHAR},
       PROCESS_DEF_KEY_ = #{processDefinitionKey, jdbcType=VARCHAR},
       JOB_DEF_ID_ = #{jobDefinitionId, jdbcType=VARCHAR},
       DEPLOYMENT_ID_ = #{deploymentId, jdbcType=VARCHAR},
       HANDLER_CFG_ = #{jobHandlerConfigurationRaw, jdbcType=VARCHAR},
       PRIORITY_ = #{priority, jdbcType=BIGINT},
       SEQUENCE_COUNTER_ = #{sequenceCounter, jdbcType=BIGINT},
       LAST_FAILURE_LOG_ID_ = #{lastFailureLogId, jdbcType=VARCHAR}
    </set>
    where ID_= #{id, jdbcType=VARCHAR}
      and REV_ = #{revision, jdbcType=INTEGER}
  </update>

    <insert id="insertEverLivingJob" parameterType="org.camunda.bpm.engine.impl.persistence.entity.EverLivingJobEntity">
        insert into ${prefix}ACT_RU_JOB (
        ID_,
        TYPE_,
        LOCK_OWNER_,
        LOCK_EXP_TIME_,
        EXCLUSIVE_,
        EXECUTION_ID_,
        PROCESS_INSTANCE_ID_,
        PROCESS_DEF_ID_,
        PROCESS_DEF_KEY_,
        RETRIES_,
        EXCEPTION_STACK_ID_,
        EXCEPTION_MSG_,
        FAILED_ACT_ID_,
        DUEDATE_,
        HANDLER_TYPE_,
        HANDLER_CFG_,
        DEPLOYMENT_ID_,
        SUSPENSION_STATE_,
        JOB_DEF_ID_,
        PRIORITY_,
        SEQUENCE_COUNTER_,
        TENANT_ID_,
        CREATE_TIME_,
        REV_
        )
        values (#{id, jdbcType=VARCHAR},
        'ever-living',
        #{lockOwner, jdbcType=VARCHAR},
        #{lockExpirationTime, jdbcType=TIMESTAMP},
        #{exclusive, jdbcType=BOOLEAN},
        #{executionId, jdbcType=VARCHAR},
        #{processInstanceId, jdbcType=VARCHAR},
        #{processDefinitionId, jdbcType=VARCHAR},
        #{processDefinitionKey, jdbcType=VARCHAR},
        #{retries, jdbcType=INTEGER},
        #{exceptionByteArrayId, jdbcType=VARCHAR},
        #{exceptionMessage, jdbcType=VARCHAR},
        #{failedActivityId, jdbcType=VARCHAR},
        #{duedate, jdbcType=TIMESTAMP},
        #{jobHandlerType, jdbcType=VARCHAR},
        #{jobHandlerConfigurationRaw, jdbcType=VARCHAR},
        #{deploymentId, jdbcType=VARCHAR},
        #{suspensionState, jdbcType=INTEGER},
        #{jobDefinitionId, jdbcType=VARCHAR},
        #{priority, jdbcType=BIGINT},
        #{sequenceCounter, jdbcType=BIGINT},
        #{tenantId, jdbcType=VARCHAR},
        #{createTime, jdbcType=TIMESTAMP},
        1
        )
    </insert>
    <!-- MESSAGE UPDATE -->

    <update id="updateEverLivingJob" parameterType="org.camunda.bpm.engine.impl.persistence.entity.EverLivingJobEntity">
        update ${prefix}ACT_RU_JOB
        <set>
            REV_ =  #{revisionNext, jdbcType=INTEGER},
            EXECUTION_ID_ = #{executionId, jdbcType=VARCHAR},
            LOCK_EXP_TIME_ = #{lockExpirationTime, jdbcType=TIMESTAMP},
            LOCK_OWNER_ = #{lockOwner, jdbcType=VARCHAR},
            RETRIES_ = #{retries, jdbcType=INTEGER},
            EXCEPTION_STACK_ID_ = #{exceptionByteArrayId, jdbcType=VARCHAR},
            EXCEPTION_MSG_ = #{exceptionMessage, jdbcType=VARCHAR},
            FAILED_ACT_ID_ = #{failedActivityId, jdbcType=VARCHAR},
            DUEDATE_ = #{duedate, jdbcType=TIMESTAMP},
            SUSPENSION_STATE_ = #{suspensionState, jdbcType=INTEGER},
            PROCESS_DEF_ID_ = #{processDefinitionId, jdbcType=VARCHAR},
            PROCESS_DEF_KEY_ = #{processDefinitionKey, jdbcType=VARCHAR},
            JOB_DEF_ID_ = #{jobDefinitionId, jdbcType=VARCHAR},
            DEPLOYMENT_ID_ = #{deploymentId, jdbcType=VARCHAR},
            HANDLER_CFG_ = #{jobHandlerConfigurationRaw, jdbcType=VARCHAR},
            PRIORITY_ = #{priority, jdbcType=BIGINT},
            SEQUENCE_COUNTER_ = #{sequenceCounter, jdbcType=BIGINT},
            LAST_FAILURE_LOG_ID_ = #{lastFailureLogId, jdbcType=VARCHAR}
        </set>
        where ID_= #{id, jdbcType=VARCHAR}
        and REV_ = #{revision, jdbcType=INTEGER}
    </update>

    <!-- ACQUIRABLE JOB UPDATE -->
    <update id="updateAcquirableJob" parameterType="org.camunda.bpm.engine.impl.persistence.entity.AcquirableJobEntity">
      update ${prefix}ACT_RU_JOB
      <set>
          REV_ =  #{revisionNext, jdbcType=INTEGER},
          LOCK_EXP_TIME_ = #{lockExpirationTime, jdbcType=TIMESTAMP},
          LOCK_OWNER_ = #{lockOwner, jdbcType=VARCHAR},
          DUEDATE_ = #{duedate, jdbcType=TIMESTAMP},
          PROCESS_INSTANCE_ID_ = #{processInstanceId, jdbcType=VARCHAR},
          EXCLUSIVE_ = #{exclusive, jdbcType=BOOLEAN},
      </set>
      where ID_= #{id, jdbcType=VARCHAR}
        and REV_ = #{revision, jdbcType=INTEGER}
    </update>

</mapper>
